package com.client.koshercook.server;

import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.gwt.user.client.rpc.IsSerializable;

/** Creating an object with Key of a recipe and its weight
 * Calculating the weight is implemented in this class*/
@PersistenceCapable
public class KeyWithFavorite implements Comparable<KeyWithFavorite> ,IsSerializable{
    @PrimaryKey
    @Persistent
	private RecipeInfo key;
	
	@Persistent
	private int favoriteWeight; //the higher the weight - the better priority to show user. (might be negative)
	
	/** Calculating the recipe weight if user have ings ingredients
	 * @pre ings,recipe != null*/
	public KeyWithFavorite(RecipeInfo recipe, Accounts acc,int ingsSize) {
		this.key = recipe;
		favoriteWeight=0;
	
		int ratio;
		if (ingsSize<3)
			ratio = 1;
		else
			ratio = ingsSize/3;
			
		favoriteWeight= favoriteWeight - (9*(recipe.getIngredients().size()-ratio)+6*ratio)/3;  //try to estimate the final count 
		
		//according to other recipe statistics
		favoriteWeight = favoriteWeight + recipe.getNumOfFavorites();
		
		int graders = recipe.getNumOfGraders();
		if(graders>4)
			favoriteWeight = favoriteWeight + 10*(recipe.getGrade()-3);
		else
			favoriteWeight = favoriteWeight + 2*graders*(recipe.getGrade()-3);
		
		
		//according to user's preferances
		if(acc!=null) {
			int myGrade = acc.getRankForRecipe(recipe.getLink());
			if(myGrade==1) favoriteWeight = favoriteWeight - 40;
			else if(myGrade==2) favoriteWeight = favoriteWeight - 20;
			else if(myGrade==4) favoriteWeight = favoriteWeight + 5;
			else if(myGrade==5) favoriteWeight = favoriteWeight + 10;
			
			int uploaderPopularity = acc.getUploaderPopularity(recipe.getUploader());
			int numFavs = acc.getFavorites_name().size();
			if(numFavs<4) favoriteWeight = favoriteWeight + uploaderPopularity*5;
			else if(numFavs<7) favoriteWeight = favoriteWeight + uploaderPopularity*4;
			else if(numFavs<12) favoriteWeight = favoriteWeight + uploaderPopularity*3;
			else if(numFavs<23) favoriteWeight = favoriteWeight + uploaderPopularity*2;
			else favoriteWeight = favoriteWeight + uploaderPopularity;
		}
	}
	
	/**get the key of the recipe*/
	public RecipeInfo getKey() {
		return key;
	}
	
	/**get the calculated weight of the recipe*/
	public int getWeight() {
		return favoriteWeight;
	}
	
	/**change the weight of the recipe*/
	public void setWeight(int weight) {
		this.favoriteWeight = weight;
	}
	
	/**compare function for sorting in decreasing way according to weight, else according to num of elements, else by name
	 * @example Collections.sort(list{4,7,2}) gives list{7,4,2}
	 */
	public int compareTo(KeyWithFavorite other) {
		if(favoriteWeight>other.getWeight()) return -1;
		if(favoriteWeight<other.getWeight()) return 1;
		if (key.getIngredients().size() < other.getKey().getIngredients().size()) return -1;
		if (key.getIngredients().size() > other.getKey().getIngredients().size()) return 1;
		return key.getRecipeName().compareTo(other.getKey().getRecipeName());
		}
}
